﻿// -----------------------------------------------------------------------
// <copyright file="CreateCar.cs" company="">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace Ex03.GarageLogic
{
    using System;
    using System.Collections.Generic;
    using System.Text;

    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    public enum eSupportedVehicleTypes
    {
        PrivateCar = 1,
        Motorcycle = 2,
        Truck = 3
    }

    public enum eEngineTypes
    {
        FuelEngine = 1,
        ElectricEngine = 2
    }

    public static class CreateCar
    {
        public static Vehicle CreateNewPrivateCar(string i_CarModel, string i_CarPlateNum, eEngineTypes i_EngineType, float i_CurrentEnergyLevel, string i_TiresManufacturer, float i_CurrentAirPressure, eColor i_CarColor, eNumOfDoors i_NumOfDoors)
        {
            EnergySource carEnergySource = null;

            if (i_EngineType == eEngineTypes.FuelEngine)
            {
                carEnergySource = VehicleFuelBasedEngineConfig(PrivateCar.MaxFuelTankCapacity, i_CurrentEnergyLevel, PrivateCar.TypeFuel);
            }
            else if (i_EngineType == eEngineTypes.ElectricEngine)
            {
                carEnergySource = VehicleElectricBasedEngineConfig(PrivateCar.MaxBaterryLife, i_CurrentEnergyLevel);
            }

            List<Tire> carTires = VehicleTiresConfig(i_TiresManufacturer, i_CurrentAirPressure, PrivateCar.MaxAirPressure, PrivateCar.NumOfTires);
            Vehicle privateCarToCreate = new PrivateCar(i_CarModel, i_CarPlateNum, carTires, carEnergySource, i_CarColor, i_NumOfDoors);

            return privateCarToCreate;
        }

        public static Vehicle CreateNewMotorcycle(string i_MotorcycleModel, string i_MotorCyclePlateNumber, eEngineTypes i_EngineType, float i_CurrentEnergyLevel, string i_TiresManufacturer, float i_CurrentAirPressure, int i_EngineCapacity, eLicenseType i_LicenseType)
        {
            EnergySource motorcycleEnergySource = null;
            if (i_EngineType == eEngineTypes.FuelEngine)
            {
                motorcycleEnergySource = VehicleFuelBasedEngineConfig(Motorcycle.MaxFuelTankCapacity, i_CurrentEnergyLevel, Motorcycle.TpyeFuel);
            }
            else if (i_EngineType == eEngineTypes.ElectricEngine)
            {
                motorcycleEnergySource = VehicleElectricBasedEngineConfig(Motorcycle.MaxBatteryLife, i_CurrentEnergyLevel);
            }

            List<Tire> motorcycleTires = VehicleTiresConfig(i_TiresManufacturer, i_CurrentAirPressure, Motorcycle.MaxAirPressure, Motorcycle.NumOfTires);
            Vehicle motorcycleToCreate = new Motorcycle(i_MotorcycleModel, i_MotorCyclePlateNumber, motorcycleTires, motorcycleEnergySource, i_EngineCapacity, i_LicenseType);

            return motorcycleToCreate;
        }

        public static Vehicle CreateNewTruck(string i_TruckModel, string i_TruckPlateNumber, eEngineTypes i_EngineType, float i_CurrentEnergyLevel, string i_TiresManufacturer, float i_CurrentAirPressure, float i_VolumeCapacity, bool i_IsHazardousMaterials)
        {
            EnergySource truckEnergySource = null;
            if (i_EngineType == eEngineTypes.ElectricEngine)
            {
                throw new ArgumentException("Truck cannot be with an electric engine");
            }
            else if (i_EngineType == eEngineTypes.FuelEngine)
            {
                truckEnergySource = VehicleFuelBasedEngineConfig(Truck.MaxFuelTankCapacity, i_CurrentEnergyLevel, Truck.TypeFuel);
            }

            List<Tire> truckTires = VehicleTiresConfig(i_TiresManufacturer, i_CurrentAirPressure, Truck.MaxAirPressure, Truck.NumOfTires);
            Vehicle truckToCreate = new Truck(i_TruckModel, i_TruckPlateNumber, truckTires, truckEnergySource, i_VolumeCapacity, i_IsHazardousMaterials);

            return truckToCreate;
        }

        /// <summary>
        /// creates a fuel engine for the vehicle with all the parameters
        /// </summary>
        /// <returns>fuelEngine</returns>
        private static EnergySource VehicleFuelBasedEngineConfig(float i_MaxFuelTankCapacity, float i_CurrentFuelTankCapacity, eTypeOfFuel i_FuelType)
        {
            if (i_CurrentFuelTankCapacity > i_MaxFuelTankCapacity || i_CurrentFuelTankCapacity < 0)
            {
                throw new ValueOutOfRangeException(0, i_MaxFuelTankCapacity, "Current fuel tank capacity is not between limits");
            }

            EnergySource vehicleEnergySource = new Fuel();
            vehicleEnergySource.MaxEnergyLevel = i_MaxFuelTankCapacity;
            vehicleEnergySource.CurrentEnergyLevel = i_CurrentFuelTankCapacity;
            if (vehicleEnergySource is Fuel)
            {
                Fuel fuelEngine = (Fuel)vehicleEnergySource;
                fuelEngine.FuelType = i_FuelType;
            }

            return vehicleEnergySource;
        }

        /// <summary>
        /// creates an electric engine for the vehicle with all the parameters
        /// </summary>
        /// <returns>electricEngine</returns>
        private static EnergySource VehicleElectricBasedEngineConfig(float i_MaxBatteryLife, float i_CurrentBatteryLife)
        {
            if (i_CurrentBatteryLife > i_MaxBatteryLife || i_CurrentBatteryLife < 0)
            {
                throw new ValueOutOfRangeException(0, i_MaxBatteryLife, "Current battery life time is not between limits");
            }

            EnergySource vehicleEnergySource = new Electric();
            vehicleEnergySource.MaxEnergyLevel = i_MaxBatteryLife;
            vehicleEnergySource.CurrentEnergyLevel = i_CurrentBatteryLife;

            return vehicleEnergySource;
        }

        private static List<Tire> VehicleTiresConfig(string i_TiresManufacturer, float i_CurrentAirPressure, float i_MaxAirPressure, int i_NumOfTires)
        {
            if (i_CurrentAirPressure > i_MaxAirPressure || i_CurrentAirPressure < 0)
            {
                throw new ValueOutOfRangeException(0, i_MaxAirPressure, "Current air pressure is not between limits");
            }

            List<Tire> vehicleTires = new List<Tire>();
            for (int i = 0; i < i_NumOfTires; i++)
            {
                Tire tire = new Tire(i_TiresManufacturer, i_CurrentAirPressure, i_MaxAirPressure);
                vehicleTires.Add(tire);
            }

            return vehicleTires;
        }
    }
}
